package graduation.project.testcase.strategy;

import graduation.project.body.OriginExpression;
import graduation.project.body.TestCase;
import graduation.project.body.TestCases;
import graduation.project.exception.NonExpressionException;

import java.util.ArrayList;
import java.util.LinkedHashSet;

public class MCDCGenerator implements TestSetGenerator {

	public TestCases generateTestCases(String expression, int testCaseNumber) {

		try{
			OriginExpression originEx = new OriginExpression(expression);
			return generateTestCases(originEx, testCaseNumber);
		}catch(NonExpressionException e){
			System.out.println("the String is not invalid expression.");
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * the strategy is that: first select the term with max literals. then... ...
	 */
	public TestCases generateTestCases(OriginExpression expression,
			int testCaseNumber) {
		
		StringBuffer model = new StringBuffer().append(expression.getModel());
		TestCases result = new TestCases(expression.getExpression(), model.toString(), "MCDC");
		String idnf = expression.getIDNF();
		LinkedHashSet<TestCase> testSet = new LinkedHashSet<TestCase>();
		
		int[][] utpSet = expression.getUtpSet();
		int[][][] nfpSet = expression.getNfpSet();
		
		String[] terms = idnf.replaceAll("!", "").split("\\+");
		int selectedTerm =0;
		int literalNum = 0;
		for(int i = 0; i < terms.length; i++)
			if(terms[i].length() > literalNum){
				selectedTerm = i;
				literalNum = terms[i].length();
			}
		
		for(int i = 0; i < terms[selectedTerm].length(); i++)
			model.deleteCharAt(model.indexOf("" + terms[selectedTerm].charAt(i)));
		testSet.add(new TestCase(utpSet[selectedTerm][0], true));
		for(int i = 0; i < literalNum; i++)
			testSet.add(new TestCase(nfpSet[selectedTerm][i][0], false));
		
		for(int i = 0; i < terms.length; i++){
			char liter;
			int j = 0;
			boolean flag = false;
			while(model.length() > 0 && j < model.length()){
				liter = model.charAt(j);
				int pos = terms[i].indexOf(liter);
				if(pos < 0){
					j++;
					continue;
				}
				flag = true;
				testSet.add(new TestCase(nfpSet[i][pos][0], false));
				model.deleteCharAt(j);
			}
			if(flag)
				testSet.add(new TestCase(utpSet[i][0], true));
		}
		
		ArrayList<TestCase> set = new ArrayList<TestCase>();
		set.addAll(testSet);
		result.setTestSet(set);
		return result;
	}
	
	public static void main(String[] args){
		MNFPGenerator mcdc = new MNFPGenerator();
		TestCases tcs = mcdc.generateTestCases("ab+cd", 2);
		ArrayList<TestCase> testSet = tcs.getTestSet();
		for(int i = 0; i < testSet.size(); i++){
			System.out.println(i + ": " + testSet.get(i).getTestData() + ", expectant: " + testSet.get(i).getExpectantResult());
		}
	}
}
